package com.lee.security.provider.social;

import com.google.common.collect.Lists;
import com.lee.domain.Employee;
import com.lee.domain.Role;
import com.lee.repository.EmployeeRepository;
import com.lee.repository.EmployeeSocialRepository;
import com.lee.vo.EmployeeAuthInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsChecker;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * @author Lee
 * @date 2018年6月1日
 */
@Component
public class SocialAuthenticationProvider implements AuthenticationProvider {// OpenID认证提供者

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private SocialDetailsService socialDetailsService;

    @Autowired
    private SocialTokenCheckManager socialTokenCheckManager;

    @Autowired
    private UserDetailsChecker accountStatusUserDetailsChecker;

    /*
     * (non-Javadoc)
     *
     * @see org.springframework.security.authentication.AuthenticationProvider#
     * authenticate(org.springframework.security.core.Authentication)
     */

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        SocialAuthenticationToken authenticationToken = (SocialAuthenticationToken) authentication;

        String openId = String.valueOf(authenticationToken.getPrincipal());

        String providerId = authenticationToken.getProviderId();

        Future<Boolean> tokenCheckFuture = socialTokenCheckManager.tokenCheck(openId,
                authenticationToken.getSocialToken(), providerId);

        String username = socialDetailsService.getUsername(providerId, openId);

        UserDetails userDetails = userDetailsService.loadUserByUsername(username);

        accountStatusUserDetailsChecker.check(userDetails);

        SocialAuthenticationToken authenticationResult = new SocialAuthenticationToken(userDetails,
                userDetails.getAuthorities());

        authenticationResult.setDetails(authenticationToken.getDetails());

        boolean checkResult;
        try {
            checkResult = tokenCheckFuture.get(3, TimeUnit.SECONDS);
        } catch (Exception e) {
            throw new AuthenticationServiceException("第三方平台响应错误");
        }
        if (!checkResult)
            throw new AuthenticationServiceException("第三方平台验证失败");

        return authenticationResult;
    }

    /*
     * (non-Javadoc)
     *
     * @see org.springframework.security.authentication.AuthenticationProvider#
     * supports(java.lang.Class)
     */
    @Override
    public boolean supports(Class<?> authentication) {
        return SocialAuthenticationToken.class.isAssignableFrom(authentication);
    }

}
